package com.study.springmvc.servlet;

import com.alibaba.fastjson.JSON;
import com.study.springmvc.context.BeanFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author lupengwei 2021/5/15 18:44
 */
public class DispatchServlet extends HttpServlet {
    
    /**
     * 配置项
     */
    private Properties properties;
    
    /**
     * 容器
     */
    private BeanFactory context;
    
    /**
     * 处理器映射器解析器
     */
    private HandlerMappingResolver handlerMappingResolver;
    
    private SecurityMappingResolver securityMappingResolver;
    
    @Override
    public void init() throws ServletException {
        // 加载配置文件
        this.properties = loadConfig();
        
        // 初始化容器、扫描包、注入依赖
        this.context = initContext(properties);
        
        // 初始化权限验证器
        securityMappingResolver = initSecurityMappingResolver(context, properties);
        
        // 初始化 HandlerMapping
        this.handlerMappingResolver = initHandlerMapping(context, properties);
    }
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        doDispatch(req, resp);
    }
    
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        doDispatch(req, resp);
    }
    
    
    private void doDispatch(HttpServletRequest req, HttpServletResponse resp) {
        String username = req.getParameter("username");
        username = username == null ? "" : username;
        
        // 权限验证解析器
        boolean result = securityMappingResolver.verifyPermission(req.getRequestURI(), username);
        Object data;
        if (!result) {
            data = "You do not have access";
        } else {
            // 根据 URL 获取 Handler
            Handler handler = handlerMappingResolver.getHandler(req);
    
            // 获取知悉方法的参数
            Map<String, Object> paramMap = new HashMap<>();
            Enumeration<String> parameterNames = req.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String paramName = parameterNames.nextElement();
                Object value = req.getParameter(paramName);
                paramMap.put(paramName, value);
            }
    
            // 执行方法返回数据
            data = handler.invoke(paramMap);
        }
        
        try {
            PrintWriter printWriter = resp.getWriter();
            printWriter.write(JSON.toJSONString(data));
            printWriter.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    
    private Properties loadConfig() {
        String contextConfigLocation = getServletConfig().getInitParameter("contextConfigLocation");
        // 读取配置文件
        Properties properties = new Properties();
        String path = contextConfigLocation.replace("classpath:", "");
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(path);
        try {
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }
    
    
    private BeanFactory initContext(Properties properties) {
        return new BeanFactory(properties);
    }
    
    
    private HandlerMappingResolver initHandlerMapping(BeanFactory context, Properties properties) {
        return new HandlerMappingResolver(context, properties);
    }
    
    
    private SecurityMappingResolver initSecurityMappingResolver(BeanFactory context, Properties properties) {
        return new SecurityMappingResolver(context, properties);
    }
}
